package com.feiyisys.controller;

import com.feiyisys.annotation.AdminRequired;
import com.feiyisys.common.Result;
import com.feiyisys.dto.FeedbackDTO;
import com.feiyisys.dto.FeedbackQueryDTO;
import com.feiyisys.dto.FeedbackReplyDTO;
import com.feiyisys.dto.FeedbackSubmitDTO;
import com.feiyisys.entity.Feedback;
import com.feiyisys.service.FeedbackService;
import com.feiyisys.utils.JwtUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;

/**
 * <p>
 * 用户反馈控制器
 * </p>
 *
 * @author system
 * @since 2025-10-14
 */
@RestController
@RequestMapping("/feedback")
@CrossOrigin("*")
@Slf4j
public class FeedbackController {

    @Resource
    private FeedbackService feedbackService;

    @Resource
    private JwtUtil jwtUtil;

    /**
     * 提交用户反馈
     */
    @PostMapping("/submit")
    public Result<Boolean> submitFeedback(
            @Valid @RequestBody FeedbackSubmitDTO feedbackSubmitDTO,
            HttpServletRequest request) {
        try {
            // 解析token获取用户ID
            Long userId = getUserIdFromToken(request);

            // 转换DTO并设置用户ID
            Feedback feedback = BeanUtil.copyProperties(feedbackSubmitDTO, Feedback.class);
            feedback.setUserId(userId);

            boolean success = feedbackService.submitFeedback(feedback);
            return success ? Result.success(true) : Result.error("提交反馈失败");
        } catch (Exception e) {
            log.error("提交反馈失败", e);
            return Result.error("提交反馈失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户的反馈列表 (GET方法)
     */
    @GetMapping("/user")
    public Result<IPage<FeedbackDTO>> getUserFeedbacks(FeedbackQueryDTO queryDTO, HttpServletRequest request) {
        return getUserFeedbacksInternal(queryDTO, request);
    }

    /**
     * 获取用户的反馈列表 (POST方法) - 为了兼容前端请求
     */
    @PostMapping("/user/list")
    public Result<IPage<FeedbackDTO>> getUserFeedbacksPost(@RequestBody FeedbackQueryDTO queryDTO, HttpServletRequest request) {
        return getUserFeedbacksInternal(queryDTO, request);
    }

    /**
     * 内部方法：获取用户的反馈列表
     */
    private Result<IPage<FeedbackDTO>> getUserFeedbacksInternal(FeedbackQueryDTO queryDTO, HttpServletRequest request) {
        try {
            // 解析token获取用户ID
            Long userId = getUserIdFromToken(request);

            // 设置查询参数
            queryDTO.setUserId(userId);

            // 获取反馈列表
            IPage<Feedback> feedbackPage = feedbackService.getUserFeedbacks(queryDTO);

            // 转换为DTO
            IPage<FeedbackDTO> dtoPage = feedbackPage.convert(this::convertToDTO);

            return Result.success(dtoPage);
        } catch (Exception e) {
            log.error("获取用户反馈列表失败", e);
            return Result.error("获取用户反馈列表失败：" + e.getMessage());
        }
    }

    /**
     * 管理员回复反馈
     */
    @AdminRequired("管理员回复反馈")
    @PostMapping("/reply")
    public Result<Boolean> replyFeedback(@Valid @RequestBody FeedbackReplyDTO replyDTO) {
        // 验证参数
        if (replyDTO.getFeedbackId() == null || replyDTO.getFeedbackId() <= 0) {
            return Result.error("无效的反馈ID");
        }
        if (StrUtil.isBlank(replyDTO.getReplyContent())) {
            return Result.error("回复内容不能为空");
        }

        // 验证反馈是否存在
        if (feedbackService.getById(replyDTO.getFeedbackId()) == null) {
            return Result.error("反馈不存在");
        }

        boolean success = feedbackService.replyFeedback(replyDTO.getFeedbackId(), replyDTO.getReplyContent());
        return success ? Result.success(true) : Result.error("回复反馈失败");
    }

    /**
     * 更新反馈状态
     */
    @AdminRequired("更新反馈状态")
    @PutMapping("/status/{feedbackId}")
    public Result<Boolean> updateStatus(
            @PathVariable Long feedbackId,
            @RequestParam Byte status) {
        // 验证状态值和反馈ID
        if (status == null || (status != 0 && status != 1 && status != 2)) {
            return Result.error("无效的状态值，状态值必须为0、1或2");
        }
        if (feedbackId == null || feedbackId <= 0) {
            return Result.error("无效的反馈ID");
        }

        boolean success = feedbackService.updateFeedbackStatus(feedbackId, status);
        return success ? Result.success(true) : Result.error("更新状态失败");
    }

    /**
     * 管理员获取所有反馈 (GET方法)
     */
    @AdminRequired("获取所有反馈列表")
    @GetMapping("/all")
    public Result<IPage<FeedbackDTO>> getAllFeedbacks(FeedbackQueryDTO queryDTO) {
        return getAllFeedbacksInternal(queryDTO);
    }

    /**
     * 管理员获取所有反馈 (POST方法) - 为了兼容前端请求
     */
    @AdminRequired("获取所有反馈列表")
    @PostMapping("/all/list")
    public Result<IPage<FeedbackDTO>> getAllFeedbacksPost(@RequestBody FeedbackQueryDTO queryDTO) {
        return getAllFeedbacksInternal(queryDTO);
    }

    /**
     * 内部方法：管理员获取所有反馈
     */
    private Result<IPage<FeedbackDTO>> getAllFeedbacksInternal(FeedbackQueryDTO queryDTO) {
        IPage<Feedback> feedbackPage = feedbackService.getAllFeedbacks(queryDTO);
        IPage<FeedbackDTO> dtoPage = feedbackPage.convert(this::convertToDTO);
        return Result.success(dtoPage);
    }

    /**
     * 获取单个反馈详情
     */
    @GetMapping("/{id}")
    public Result<FeedbackDTO> getFeedbackDetail(@PathVariable Long id, HttpServletRequest request) {
        try {
            // 验证用户权限
            Long userId = getUserIdFromToken(request);

            // 获取反馈
            Feedback feedback = feedbackService.getById(id);
            if (feedback == null) {
                return Result.error("反馈不存在");
            }

            // 检查是否为管理员或反馈所有者
            if (userId != 0 && !feedback.getUserId().equals(userId)) {
                return Result.error("没有权限查看此反馈");
            }

            // 转换为DTO
            FeedbackDTO dto = convertToDTO(feedback);

            return Result.success(dto);
        } catch (Exception e) {
            log.error("获取反馈详情失败", e);
            return Result.error("获取反馈详情失败：" + e.getMessage());
        }
    }

    /**
     * 编辑反馈
     */
    @PutMapping("/{id}")
    public Result<Boolean> updateFeedback(
            @PathVariable Long id,
            @RequestBody FeedbackSubmitDTO feedbackDTO,
            HttpServletRequest request) {
        try {
            // 获取用户ID并验证
            Long userId = getUserIdFromToken(request);

            // 获取并验证反馈
            Feedback feedback = feedbackService.getById(id);
            if (feedback == null) {
                return Result.error("反馈不存在");
            }
            if (!feedback.getUserId().equals(userId)) {
                return Result.error("没有权限编辑此反馈");
            }
            // 已回复的反馈不允许编辑
            if (feedback.getStatus() != null && feedback.getStatus() == 2) {
                return Result.error("已回复的反馈不允许编辑");
            }

            // 更新反馈信息
            Feedback updateFeedback = new Feedback();
            updateFeedback.setId(id);
            updateFeedback.setTitle(feedbackDTO.getTitle());
            updateFeedback.setContent(feedbackDTO.getContent());
            updateFeedback.setContactInfo(feedbackDTO.getContactInfo());

            boolean success = feedbackService.updateFeedback(updateFeedback);
            return success ? Result.success(true) : Result.error("编辑反馈失败");
        } catch (Exception e) {
            log.error("编辑反馈失败", e);
            return Result.error("编辑反馈失败：" + e.getMessage());
        }
    }

    /**
     * 删除反馈
     */
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteFeedback(
            @PathVariable Long id,
            HttpServletRequest request) {
        try {
            // 获取用户ID
            Long userId = getUserIdFromToken(request);

            // 获取反馈
            Feedback feedback = feedbackService.getById(id);
            if (feedback == null) {
                return Result.error("反馈不存在");
            }

            boolean success = feedbackService.deleteFeedback(id, userId);
            return success ? Result.success(true) : Result.error("删除反馈失败");
        } catch (Exception e) {
            log.error("删除反馈失败", e);
            return Result.error("删除反馈失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除反馈（仅管理员）
     */
    @AdminRequired("批量删除反馈")
    @PostMapping("/batch-delete")
    public Result<Boolean> batchDeleteFeedbacks(@RequestBody List<Long> ids) {
        try {
            // 验证参数
            if (ids == null || ids.isEmpty()) {
                return Result.error("请选择要删除的反馈");
            }

            // 验证并批量删除，使用管理员权限（userId = 0）
            boolean allSuccess = true;
            for (Long id : ids) {
                if (id == null || id <= 0) {
                    return Result.error("包含无效的反馈ID");
                }

                if (feedbackService.getById(id) == null) {
                    return Result.error("反馈ID " + id + " 不存在");
                }

                boolean success = feedbackService.deleteFeedback(id, 0L);
                if (!success) {
                    allSuccess = false;
                    log.warn("删除反馈失败，ID: {}", id);
                }
            }

            return allSuccess ? Result.success(true) : Result.error("部分反馈删除失败");
        } catch (Exception e) {
            log.error("批量删除反馈失败", e);
            return Result.error("批量删除反馈失败：" + e.getMessage());
        }
    }

    /**
     * 从请求头token中获取用户ID
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StrUtil.isBlank(token) || !token.startsWith("Bearer ")) {
            throw new RuntimeException("未授权访问，请先登录");
        }

        String jwtToken = token.substring(7);
        Claims claims = jwtUtil.parseToken(jwtToken);
        Long userId = claims.get("id", Long.class);

        if (userId == null || userId <= 0) {
            throw new RuntimeException("无效的用户信息");
        }

        return userId;
    }

    /**
     * 将Feedback实体转换为FeedbackDTO
     */
    private FeedbackDTO convertToDTO(Feedback feedback) {
        FeedbackDTO dto = new FeedbackDTO();
        dto.setId(feedback.getId());
        dto.setUserId(feedback.getUserId());
        dto.setTitle(feedback.getTitle());
        dto.setContent(feedback.getContent());
        dto.setContactInfo(feedback.getContactInfo());
        dto.setStatus(feedback.getStatus());
        dto.setReplyContent(feedback.getReplyContent());
        dto.setReplyTime(feedback.getReplyTime());
        dto.setCreateTime(feedback.getCreateTime());
        dto.setUsername("用户" + feedback.getUserId());

        // 设置状态描述
        setStatusDescription(dto);

        return dto;
    }

    /**
     * 设置状态描述
     */
    private void setStatusDescription(FeedbackDTO dto) {
        if (dto.getStatus() != null) {
            switch (dto.getStatus()) {
                case 0:
                    dto.setStatusDesc("未处理");
                    break;
                case 1:
                    dto.setStatusDesc("已处理");
                    break;
                case 2:
                    dto.setStatusDesc("已回复");
                    break;
                default:
                    dto.setStatusDesc("未知状态");
            }
        }
    }
}